package cn.fresh.xuanyuan.module.member.service.user;

import cn.fresh.xuanyuan.framework.common.pojo.PageParam;
import cn.fresh.xuanyuan.framework.common.pojo.PageResult;
import cn.fresh.xuanyuan.framework.common.util.date.LocalDateTimeUtils;
import cn.fresh.xuanyuan.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.fresh.xuanyuan.module.member.dal.dataobject.user.MemberCollectDO;
import cn.fresh.xuanyuan.module.member.dal.dataobject.user.MemberLikeDO;
import cn.fresh.xuanyuan.module.member.dal.mysql.user.MemberCollectMapper;
import cn.fresh.xuanyuan.module.member.dal.mysql.user.MemberLikeMapper;
import cn.fresh.xuanyuan.module.member.vo.MemberCollectVO;
import cn.fresh.xuanyuan.module.member.vo.MemberLikeVO;
import cn.fresh.xuanyuan.module.product.api.spu.ProductSpuApi;
import cn.fresh.xuanyuan.module.product.api.spu.dto.ProductSpuRespDTO;
import cn.hutool.core.collection.CollectionUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class MemberCollectServiceImpl implements MemberCollectService {

    @Resource
    private MemberCollectMapper memberCollectMapper;

    @Resource
    private MemberLikeMapper memberLikeMapper;

    @Resource
    private ProductSpuApi productSpuApi;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addLike(Long spuId, Long userId) {
        ProductSpuRespDTO spu = productSpuApi.getSpu(spuId).getCheckedData();
        if(spu != null) {
            MemberLikeDO isExist = memberLikeMapper.isExist(userId, spuId);
            if(isExist != null) {
                subLikeById(isExist);
            }
            else {
                MemberLikeDO likeDO = MemberLikeDO.builder().userId(userId).spuId(spuId).build();
                likeDO.setDeleted(false);
                memberLikeMapper.insert(likeDO);
                ProductSpuRespDTO respDTO = new ProductSpuRespDTO();
                respDTO.setId(spuId);
                productSpuApi.addLike(respDTO);
            }
            return 1;
        }
        return 0;
    }

    @Override
    public int addCollect(Long spuId, Long userId) {
        ProductSpuRespDTO spu = productSpuApi.getSpu(spuId).getCheckedData();
        if(spu != null) {
            LambdaQueryWrapperX<MemberCollectDO> queryWrapperX = new LambdaQueryWrapperX<>();
            queryWrapperX.eq(MemberCollectDO::getProductId, spuId).eq(MemberCollectDO::getUserId, userId).eq(MemberCollectDO::getDeleted, false);
            MemberCollectDO c = memberCollectMapper.selectOne(queryWrapperX);
            if(c == null) {
                MemberCollectDO collectDO = MemberCollectDO.builder()
                        .orchardName(spu.getOrchardName())
                        .orchardId(spu.getOrchardId())
                        .productImage(spu.getPicUrl())
                        .productName(spu.getName())
                        .productId(spuId)
                        .userId(userId)
                        .build();
                collectDO.setDeleted(false);
                collectDO.setCreateTime(LocalDateTime.now());
                ProductSpuRespDTO respDTO = new ProductSpuRespDTO();
                respDTO.setId(spuId);
                memberCollectMapper.insert(collectDO);
                productSpuApi.addCollect(respDTO);
                return 1;
            }
        }
        return 0;
    }

    @Override
    public int subLike(Long spuId, Long userId) {
        memberLikeMapper.remove(userId, spuId);
        ProductSpuRespDTO respDTO = new ProductSpuRespDTO();
        respDTO.setId(spuId);
        productSpuApi.subLike(respDTO);
        return 1;
    }

    @Override
    public int subLikeById(MemberLikeDO likeDO) {
        memberLikeMapper.deleteById(likeDO.getId());
        ProductSpuRespDTO respDTO = new ProductSpuRespDTO();
        respDTO.setId(likeDO.getSpuId());
        productSpuApi.subLike(respDTO);
        return 1;
    }

    @Override
    public void removeCollect(Long id, Long userId) {
        LambdaQueryWrapperX<MemberCollectDO> queryWrapperX = new LambdaQueryWrapperX<>();
        queryWrapperX.eq(MemberCollectDO::getId, id).eq(MemberCollectDO::getUserId, userId);
        memberCollectMapper.delete(queryWrapperX);
    }

    @Override
    public PageResult<MemberCollectVO> myCollectList(Long userId, PageParam pageParam) {
        PageResult<MemberCollectDO> page = memberCollectMapper.selectPage(userId, pageParam);
        List<MemberCollectVO> data = new ArrayList<>();
        Long total = 0L;
        if(page != null && CollectionUtil.isNotEmpty(page.getList())) {
            List<MemberCollectDO> list = page.getList();
            for(MemberCollectDO c : list) {
                MemberCollectVO v = new MemberCollectVO();
                BeanUtils.copyProperties(c, v);
                data.add(v);
            }
            total = page.getTotal();
        }
        PageResult<MemberCollectVO> result = new PageResult<>(data, total);
        return result;
    }

    @Override
    public MemberLikeVO isLike(Long userId, Long spuId) {
        MemberLikeDO isExist = memberLikeMapper.isExist(userId, spuId);
        if(isExist != null) {
            MemberLikeVO vo = new MemberLikeVO();
            BeanUtils.copyProperties(isExist, vo);
            return vo;
        }
        return null;
    }

    @Override
    public MemberCollectVO isCollect(Long userId, Long spuId) {
        LambdaQueryWrapperX<MemberCollectDO> queryWrapperX = new LambdaQueryWrapperX<>();
        queryWrapperX.eq(MemberCollectDO::getProductId, spuId).eq(MemberCollectDO::getUserId, userId).eq(MemberCollectDO::getDeleted, false);
        MemberCollectDO c = memberCollectMapper.selectOne(queryWrapperX);
        if(c != null) {
            MemberCollectVO vo = new MemberCollectVO();
            BeanUtils.copyProperties(c, vo);
            return vo;
        }
        return null;
    }
}
